<!-- components/DynamicForm.vue -->
<template>
	<view class="dynamic-form">
		<uni-forms ref="formRef" :model="formData" :rules="formRules" :label-position="labelPosition"
			:label-width="labelWidth" @validate="handleValidate">
			<view v-for="(item, index) in formConfig" :key="index">
				<!-- 输入框 -->
				<view v-if="item.type === 'text'" class="form-item">
					<uni-forms-item :label="item.alias" :required="item.required" :name="item.key">
						<uni-easyinput v-model="formData[item.key]"
							:placeholder="item.placeholder || `请输入${item.alias}`" :type="item.inputType || 'text'" />
					</uni-forms-item>
				</view>

				<!-- 步进器 -->
				<view v-if="item.type === 'number'" class="form-item">
					<uni-forms-item :label="item.alias" :required="item.required" :name="item.key">
						<uni-number-box v-model="formData[item.key]" :min="item.min || 0" :max="item.max || 100"
							:step="item.step || 1" />
					</uni-forms-item>
				</view>

				<!-- 多行文本 -->
				<view v-if="item.type === 'textarea'" class="form-item">
					<uni-forms-item :label="item.alias" :required="item.required" :name="item.key">
						<uni-easyinput v-model="formData[item.key]" type="textarea"
							:placeholder="item.placeholder || `请输入${item.alias}`" :maxlength="item.maxlength || 140" />
					</uni-forms-item>
				</view>

				<!-- 下拉菜单 -->
				<view v-if="item.type === 'select'" class="form-item">
					<uni-forms-item :label="item.alias" :required="item.required" :name="item.key">
						<uni-data-select v-model="formData[item.key]" :localdata="item.options"
							:placeholder="item.placeholder || `请选择${item.alias}`" />
					</uni-forms-item>
				</view>

				<!-- 下拉菜单多选 -->
				<view v-if="item.type === 'multiple_select'" class="form-item">
					<uni-forms-item :label="item.alias" :required="item.required" :name="item.key">
						<zxz-uni-data-select v-model="formData[item.key]" :localdata="item.options" multiple
							:placeholder="item.placeholder || `请选择${item.alias}`" />
					</uni-forms-item>
				</view>

				<!-- 单选框 -->
				<view v-if="item.type === 'radio'" class="form-item">
					<uni-forms-item :label="item.alias" :required="item.required" :name="item.key">
						<uni-data-checkbox v-model="formData[item.key]" :localdata="item.options" mode="button" />
					</uni-forms-item>
				</view>

				<!-- 多选框 -->
				<view v-if="item.type === 'checkbox'" class="form-item">
					<uni-forms-item :label="item.alias" :required="item.required" :name="item.key">
						<uni-data-checkbox v-model="formData[item.key]" :localdata="item.options" multiple />
					</uni-forms-item>
				</view>

				<!-- 开关 -->
				<view v-if="item.type === 'switch'" class="form-item">
					<uni-forms-item :label="item.alias" :required="item.required" :name="item.key">
						<uni-switch v-model="formData[item.key]" />
					</uni-forms-item>
				</view>

				<!-- 密码框 -->
				<view v-if="item.type === 'password'" class="form-item">
					<uni-forms-item :label="item.alias" :required="item.required" :name="item.key">
						<uni-easyinput v-model="formData[item.key]" type="password"
							:placeholder="item.placeholder || `请输入${item.alias}`" />
					</uni-forms-item>
				</view>
			</view>
			<view>
				<uni-forms-item label="购买数量" required>
					<slot></slot>
				</uni-forms-item>
			</view>
		</uni-forms>
	</view>
</template>

<script setup>
	import {
		ref,
		watch,
		defineProps,
		defineEmits,
		computed
	} from "vue";

	const props = defineProps({
		formConfig: {
			type: Array,
			required: true,
			default: () => []
		},
		modelValue: {
			type: Object,
			default: () => ({})
		},
		labelPosition: {
			type: String,
			default: "left"
		},
		labelWidth: {
			type: [String, Number],
			default: 100
		}
	});

	const emit = defineEmits(["update:modelValue", "change", "validate"]);

	const formRef = ref(null);
	const formData = ref({
		...props.modelValue
	});

	// 生成表单验证规则
	const formRules = computed(() => {
		const rules = {};
		props.formConfig.forEach((item) => {
			if (item.rules) {
				rules[item.key] = item.rules;
			} else if (item.required) {
				rules[item.key] = {
					rules: [{
						required: true,
						errorMessage: `${item.alias}不能为空`
					}]
				};

				// 根据类型添加额外验证规则
				if (item.type === "input") {
					if (item.inputType === "number") {
						rules[item.key].rules.push({
							format: "number",
							errorMessage: `${item.alias}必须为数字`
						});
					} else if (item.inputType === "email") {
						rules[item.key].rules.push({
							format: "email",
							errorMessage: `${item.alias}格式不正确`
						});
					}
				}

				if (item.type === "password") {
					rules[item.key].rules.push({
						minLength: 6,
						maxLength: 20,
						errorMessage: `${item.alias}长度需在6-20个字符之间`
					});
				}
			}
		});
		return rules;
	});

	// 监听外部传入的modelValue变化
	watch(
		() => props.modelValue,
		(newVal) => {
			formData.value = {
				...newVal
			};
		}, {
			deep: true
		}
	);

	// 监听表单数据变化
	watch(
		formData,
		(newVal) => {
			emit("update:modelValue", newVal);
			emit("change", newVal);
		}, {
			deep: true
		}
	);

	// 验证事件
	const handleValidate = (e) => {
		emit("validate", e);
	};

	// 暴露表单验证方法
	defineExpose({
		validate: () => formRef.value.validate(),
		validateField: (props) => formRef.value.validateField(props),
		setRules: (rules) => formRef.value.setRules(rules),
		clearValidate: (props) => formRef.value.clearValidate(props),
		submit: () => formRef.value.submit()
	});
</script>